﻿//
//  YHGameSceneManager.cpp
//  ThunderWarriors
//
//  Created by mac on 12-12-22.
//
//

#include "YHGameSceneManager.h"
#include "YHClassFactory.h"

YHGameSceneManager* YHGameSceneManager::m_sharedGameSceneManager = NULL;

YHGameSceneManager::YHGameSceneManager(){
    m_sharedGameSceneManager = NULL;
    m_curRunningScene = NULL;
    m_arrayLayers = CCArray::create();
    m_arrayScenes = CCArray::create();
    m_arrayLayers->retain();
    m_arrayScenes->retain();
}

YHGameSceneManager::~YHGameSceneManager(){
    CC_SAFE_RELEASE(m_arrayScenes);
    CC_SAFE_RELEASE(m_arrayLayers);
}

YHGameSceneManager* YHGameSceneManager::sharedGameSceneManager(){
    if (m_sharedGameSceneManager == NULL)
	{
		m_sharedGameSceneManager = new YHGameSceneManager();
		if (!m_sharedGameSceneManager || !m_sharedGameSceneManager->init())
		{
			CC_SAFE_DELETE(m_sharedGameSceneManager);
            return NULL;
		}
        
	}
    
	return m_sharedGameSceneManager;
}

void YHGameSceneManager::purgeSharedGameSceneManager(){
    CC_SAFE_DELETE(m_sharedGameSceneManager);
}

bool YHGameSceneManager::init(){
    bool ret = false;
    //TODO: initialize here
    {
        ret = true;
    }
    return ret;
}

//获得当前场景
YHScene* YHGameSceneManager::getRunningScene(){
    CCDirector::sharedDirector()->drawScene();
    m_curRunningScene = (YHScene*)CCDirector::sharedDirector()->getRunningScene();
    return m_curRunningScene;
}

void YHGameSceneManager::pushScene(YHScene* scene){
    if (NULL != scene) {
        if (0 == m_arrayScenes->count()) {
            CCDirector::sharedDirector()->runWithScene(scene);
            m_arrayScenes->addObject(scene);
            m_curRunningScene = scene;
        }
        else {
            CCDirector::sharedDirector()->pushScene(scene);
            m_arrayScenes->addObject(scene);
            m_curRunningScene = scene;
        }
    }
}

YHScene* YHGameSceneManager::pushScene(string sceneClassName){
    YHScene* scene = createScene(sceneClassName);
    pushScene(scene);
    return scene;
}

YHScene* YHGameSceneManager::pushSceneWithId(string sceneClassName, GameSceneIdType sceneId){
    YHScene* scene = createSceneWithId(sceneClassName, sceneId);
    pushScene(scene);
    return scene;
}
 
void YHGameSceneManager::gotoScene(YHScene* scene){
    if (NULL != scene) {
        if (0 == m_arrayScenes->count()) {
            CCDirector::sharedDirector()->runWithScene(scene); //如果是第一次压入场景，使用runWithScene
            m_arrayScenes->addObject(scene);
            m_curRunningScene = scene;
        }
        else {
            m_arrayScenes->removeLastObject(); //移除掉最近使用的那个scene
            CCDirector::sharedDirector()->replaceScene(scene);
            m_arrayScenes->addObject(scene);
            m_curRunningScene = scene;
        }
    }
}

YHScene* YHGameSceneManager::gotoScene(string sceneClassName){
    YHScene* scene = createScene(sceneClassName);
    gotoScene(scene);
    return scene;
}

YHScene* YHGameSceneManager::gotoSceneWithId(string sceneClassName, GameSceneIdType sceneId){
    YHScene* scene = createSceneWithId(sceneClassName, sceneId);
    gotoScene(scene);
    return scene;
}



void YHGameSceneManager::popScene(){
    if (m_curRunningScene != NULL) {
        m_arrayScenes->removeObject((CCObject*)m_curRunningScene);
        CCDirector::sharedDirector()->popScene();
        CCDirector::sharedDirector()->drawScene();
        m_curRunningScene = (YHScene*)(CCDirector::sharedDirector()->getRunningScene());
    }
}

//layer加入到当前场景中，flag1和flag2可以自定义标志，data用来传递数据
YHLayer* YHGameSceneManager::openLayerByIdAndTag(string layerClassName, GameLayerIdType layerId,
                                             int flag1, int flag2, void* flagData){
    YHLayer* layer = createLayerWithId(layerClassName,layerId);
    if (NULL != layer) {
        layer->setLayerFlag1(flag1);
        layer->setLayerFlag2(flag2);
        layer->setLayerFalgData(flagData);
        pushLayer(layer);
    }
    return layer;
}

//根据layerId生成layer，然后加入到当前场景中(layerId必须唯一)
YHLayer* YHGameSceneManager::pushLayerWithId(string layerClassName, GameLayerIdType layerId){
    YHLayer* layer = createLayerWithId(layerClassName, layerId);
    pushLayer(layer);
    return layer;
}
 
//将layer加入到当前的场景中
void YHGameSceneManager::pushLayer(YHLayer* layer){
    if (m_curRunningScene != NULL && layer->getParent() == NULL) {
        m_curRunningScene->addChild(layer);
    }
    else{
        CCAssert(!0, "layer should not have a parent!");
    }
}

YHLayer* YHGameSceneManager::pushLayer(string layerClassName){
    YHLayer* layer = createLayer(layerClassName);
    pushLayer(layer);
    return layer;
}

//根据layerId，从父节点移除。(layerId必须唯一)
void YHGameSceneManager::removeLayerById(GameLayerIdType layerId){
    CCObject* pLayer = NULL;
    CCARRAY_FOREACH(m_arrayLayers, pLayer){
        YHLayer* tmpLayer = (YHLayer*) pLayer;
        if (layerId == tmpLayer->getLayerIdType()) {
            m_arrayLayers->removeObject(tmpLayer);
            tmpLayer->removeFromParentAndCleanup(true);//从父节点移除
            break;
        }
    }
}

//将layer从父节点移除
void YHGameSceneManager::removeLayer(YHLayer* layer){
    CCObject* pLayer = NULL;
    CCARRAY_FOREACH(m_arrayLayers, pLayer){
        YHLayer* tmpLayer = (YHLayer*) pLayer;
        if (tmpLayer == layer) {
            m_arrayLayers->removeObject(tmpLayer);
            tmpLayer->removeFromParentAndCleanup(true);//从父节点移除
            break;
        }
    }
}

void YHGameSceneManager::removeAllScene(){
    if (0 != m_arrayScenes->count()) {
        CCDirector::sharedDirector()->popToRootScene();
        CCDirector::sharedDirector()->drawScene();
        m_arrayScenes->removeAllObjects();
        m_curRunningScene = (YHScene*)CCDirector::sharedDirector()->getRunningScene();
        m_arrayScenes->addObject(m_curRunningScene);
    }
}

void YHGameSceneManager::removeAllLayer(){
    CCObject* pLayer = NULL;
    CCARRAY_FOREACH(m_arrayLayers, pLayer){
        YHLayer* layer = (YHLayer*) pLayer;
        layer->removeFromParentAndCleanup(true);
    }
    m_arrayLayers->removeAllObjects();
}

YHScene* YHGameSceneManager::getSceneById(GameSceneIdType sceneId){
    CCObject* pScene = NULL;
    CCARRAY_FOREACH_REVERSE(m_arrayScenes, pScene){
        YHScene* scene = (YHScene*) pScene;
        if (sceneId == scene->getGameSceneIdType()) {
            return scene;
        }
    }
    return NULL;
}

YHScene* YHGameSceneManager::createScene(string sceneClassName){
    YHScene* scene = (YHScene*) YHClassFactory::sharedClassFactory()->getClasstByName(sceneClassName);
    return scene;
}

YHScene* YHGameSceneManager::createSceneWithId(string sceneClassName, GameSceneIdType sceneId){
    YHScene* scene = createScene(sceneClassName);
    if (scene) {
        scene->setGameSceneIdType(sceneId);
    }
    return scene;
}


YHLayer* YHGameSceneManager::getLayerById(GameLayerIdType layerId){
    CCObject* pLayer = NULL;
    CCARRAY_FOREACH_REVERSE(m_arrayLayers, pLayer){
        YHLayer* layer = (YHLayer*) pLayer;
        if (layerId == layer->getLayerIdType()) {
            return layer;
        }
    }
    return NULL;
}

YHLayer* YHGameSceneManager::createLayer(string layerClassName){
    YHLayer* layer =  (YHLayer*) YHClassFactory::sharedClassFactory()->getClasstByName(layerClassName);
    return layer;
}

YHLayer* YHGameSceneManager::createLayerWithId(string layerClassName, GameLayerIdType layerId){
    YHLayer* layer = createLayer(layerClassName);
    if (layer) {
        layer->setLayerIdType(layerId);
    }
    return layer;
}

